package cn.edu.njnu.opengmpback.Modeling.service;


import cn.edu.njnu.opengmpback.Modeling.dao.ProjectDao;
import cn.edu.njnu.opengmpback.Modeling.entity.Project;
import cn.edu.njnu.opengmpback.Modeling.entity.dto.CreateProjectDTO;
import cn.edu.njnu.opengmpback.Modeling.entity.dto.ProjectPageDTO;
import cn.edu.njnu.opengmpback.Modeling.entity.dto.UpdateProjectDTO;
import cn.edu.njnu.opengmpback.common.utils.*;
import cn.edu.njnu.opengmpback.user.dao.HistoryDao;
import cn.edu.njnu.opengmpback.user.entity.History;
import cn.edu.njnu.opengmpback.user.entity.UserEntity;
import cn.edu.njnu.opengmpback.user.dao.UserDao;
import cn.edu.njnu.opengmpback.user.service.HistoryService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class ProjectService {

    @Autowired
    ProjectDao projectDao;

    @Autowired
    UserDao userDao;

    @Autowired
    HistoryDao historyDao;

    @Autowired
    CommonService commonService;

    @Autowired
    HistoryService historyService;

    @Autowired
    ConceptModelService conceptModelService;

    @Autowired
    ComputeModelService computeModelService;

    public JsonResult saveProject(CreateProjectDTO createProjectDTO, String userId){
        try{
            Project project= new Project();
            BeanUtils.copyProperties(createProjectDTO,project);

            UserEntity user = userDao.findByUserId(userId);
            project.setCreatorId(user.getUserId());
            project.setCreatorName(user.getName());
            project.setCreatorEmail(user.getEmail());
            List<String> memberList = new ArrayList<>();
            memberList.add(userId);
            project.setMemberList(memberList);

            user.getCreatedProjects().add(project.getId());
            user.getJoinedProjects().add(project.getId());
            userDao.save(user);
            projectDao.save(project);

            //创建动态
            historyService.createHistory("创建项目",user.getName() + " 创建了项目 "+project.getName(),userId, project.getId(),"");

            return ResultUtils.success(project);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"创建项目失败！");
        }
    }

    public JsonResult updateProject(UpdateProjectDTO updateProjectDTO) {
        try{
            Optional<Project> projectDB= projectDao.findById(updateProjectDTO.getId());
            if(!projectDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            Project project = projectDB.get();
            BeanUtils.copyProperties(updateProjectDTO,project);
            project.setUpdateTime(new Date());
            projectDao.save(project);

            return ResultUtils.success(project);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"更新项目失败！");
        }
    }

    public JsonResult deleteProject(String projectId, String userId) {
        try{
            Optional<Project> projectDB= projectDao.findById(projectId);
            if(!projectDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            Project project =projectDB.get();
            if(!project.getCreatorId().equals(userId)){
                return ResultUtils.error(-1,"只有创建者才能删除");
            }
            //成员退出项目
            for (String memberId : project.getMemberList()) {
                UserEntity user = userDao.findByUserId(memberId);
                user.getJoinedProjects().remove(projectId);
                userDao.save(user);
                historyService.createHistory("删除项目", project.getName() + " 项目被解散了", memberId, projectId,"");
            }
            String creatorId = project.getCreatorId();
            UserEntity user = userDao.findByUserId(creatorId);
            user.getCreatedProjects().remove(projectId);
            userDao.save(user);

            try{
                for (String s : project.getConceptModelIdList()) {
                    conceptModelService.DeleteConceptModel(s);
                }
                computeModelService.DeleteComputeModel(project.getComputeModelId());
            } catch ( Exception e ){
                log.error(e.getMessage());
            }

            projectDao.deleteById(projectId);
            return ResultUtils.success(project);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"删除项目失败！");
        }
    }

    public JsonResult joinProject(String projectId, List<String> emails, String userId) {
        try{
            List<String> success = new ArrayList<>();
            List<String> failed = new ArrayList<>();
            Project project = projectDao.findById(projectId).get();
            if(!project.getCreatorId().equals(userId)){
                return ResultUtils.error(-1,"只有创建者才能邀请");
            }
            List<String> joinIds= new ArrayList<>();
            for (String email : emails) {
                UserEntity user = userDao.findByEmail(email);
                if(user == null){
                    failed.add(email);
                    continue;
                }
                if(!user.getJoinedProjects().contains(projectId)){
                    joinIds.add(user.getUserId());
                }
                success.add(email);
            }
            projectDao.save(project);

            //动态更新
            String content = "您被邀请加入项目：" + project.getName();
            for (String memberId : joinIds) {
                historyService.createHistory("项目邀请", content, memberId, projectId, "未读");
            }
            JSONObject result = new JSONObject();
            result.put("success",success);
            result.put("failed",failed);
            return ResultUtils.success(result);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"邀请失败");
        }
    }

    public JsonResult quitProject(String projectId, List<String> userIds) {
        try{
            List<String> success = new ArrayList<>();
            List<String> failed = new ArrayList<>();
            List<String> successName = new ArrayList<>();
            Project project = projectDao.findById(projectId).get();
            for (String userId : userIds) {
                //创建者不能在此处退出
                if(userId.equals(project.getCreatorId())){
                    failed.add(userId);
                    continue;
                }
                UserEntity user = userDao.findByUserId(userId);
                if(user == null){
                    failed.add(userId);
                    continue;
                }
                user.getJoinedProjects().remove(projectId);
                userDao.save(user);
                project.getMemberList().remove(userId);
                success.add(userId);
                successName.add(user.getName());
            }
            projectDao.save(project);
            historyService.createHistory("项目成员变动", String.join(",", successName) + " 退出了 " + project.getName() + " 项目", project.getCreatorId(), projectId, "");
            for (String s : success) {
                historyService.createHistory("退出项目", "您退出了 " + project.getName() + " 项目", s, projectId, "");
            }
            JSONObject result = new JSONObject();
            result.put("success",success);
            result.put("failed",failed);
            return ResultUtils.success(result);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"退出失败");
        }
    }

    public JsonResult inquiryByPage(ProjectPageDTO projectPageDTO) {
        try{
            Pageable pageable = commonService.getProjectPageable(projectPageDTO);

            Page<Project> re = projectDao.findAllByNameLikeIgnoreCase(projectPageDTO.getSearchText(), pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败！");
        }
    }

    public JsonResult getProjectById(String projectId) {
        try{
            Optional<Project> projectDB = projectDao.findById(projectId);
            if(!projectDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            Project project = projectDB.get();
            project.setViewTimes(project.getViewTimes() + 1);
            projectDao.save(project);
            return ResultUtils.success(project);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目信息获取失败！");
        }
    }

    public JsonResult getMemberList(String projectId) {
        try{
            Optional<Project> projectDB = projectDao.findById(projectId);
            if(!projectDB.isPresent()){
                return ResultUtils.error(-1,"项目不存在");
            }
            Project project = projectDB.get();
            JSONArray memberList = new JSONArray();
            for (String memberId : project.getMemberList()) {
                UserEntity member = userDao.findByUserId(memberId);
                JSONObject userInfo = new JSONObject();
                userInfo.put("userId", member.getUserId());
                userInfo.put("name", member.getName());
                userInfo.put("avatar", member.getAvatar());
                userInfo.put("email", member.getEmail());
                userInfo.put("title", member.getTitle());
                userInfo.put("phone", member.getPhone());
                userInfo.put("country", member.getCountry());
                userInfo.put("State", member.getState());
                userInfo.put("city", member.getCity());
                userInfo.put("domain", member.getDomain());
                userInfo.put("organization", member.getOrganizations());
                memberList.add(userInfo);
            }
            return ResultUtils.success(memberList);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"成员列表获取失败！");
        }
    }
}
